const areaCompute = ({ raw, tags, areas, length }) => {
  // each area
  let result = areas.map((area) => {
    let details = area.content.map((item) => {
      /*
       "item": {
          "tag": "ZUUU_DEP_BOKIR",
          "delay": 0,
          "ratio": 18
        },
      */
      let tagIdx = tags.indexOf(item.tag);
      let taggedData = raw.map((line) => line[tagIdx]);
      // if (item.ratio > 0) {
      //   console.log("areaCompute", area.identifier, item.tag, taggedData);
      // }
      let flowOriginalQuarter = taggedData.map((cell) =>
        item.ratio > 0 ? cell : 0
      );
      let loadOriginalQuarter = flowOriginalQuarter.map(
        (cell) => cell * item.ratio
      );
      let flowCalibratedQuarter = flowOriginalQuarter.map((cell, i, arr) => {
        let newCell = 0;
        if (item.delay == 0) {
          newCell = arr[i];
        } else if (item.delay > 0 && i > 0) {
          newCell += arr[i - 1] * (item.delay / 15);
          newCell += arr[i] * (1 - item.delay / 15);
        } else if (item.delay > 15 && i > 1) {
          newCell += arr[i - 2] * (item.delay / 15 - 1);
        } else {
          newCell = cell;
        }
        return newCell;
      });
      let loadCalibratedQuarter = flowCalibratedQuarter.map(
        (cell) => cell * item.ratio
      );
      let flowOriginalWhole = flowOriginalQuarter.map(
        (val, i, arr) =>
          val +
          (i < arr.length - 1 ? arr[i + 1] : 0) +
          (i < arr.length - 2 ? arr[i + 2] : 0) +
          (i < arr.length - 3 ? arr[i + 3] : 0)
      );
      let flowOriginalHalf = flowOriginalQuarter.map(
        (val, i, arr) => val + (i < arr.length - 1 ? arr[i + 1] : 0)
      );
      let flowCalibratedWhole = flowCalibratedQuarter.map(
        (val, i, arr) =>
          val +
          (i < arr.length - 1 ? arr[i + 1] : 0) +
          (i < arr.length - 2 ? arr[i + 2] : 0) +
          (i < arr.length - 3 ? arr[i + 3] : 0)
      );
      let flowCalibratedHalf = flowCalibratedQuarter.map(
        (val, i, arr) => val + (i < arr.length - 1 ? arr[i + 1] : 0)
      );
      let loadOriginalWhole = loadOriginalQuarter.map(
        (val, i, arr) =>
          val +
          (i < arr.length - 1 ? arr[i + 1] : 0) +
          (i < arr.length - 2 ? arr[i + 2] : 0) +
          (i < arr.length - 3 ? arr[i + 3] : 0)
      );
      let loadOriginalHalf = loadOriginalQuarter.map(
        (val, i, arr) => val + (i < arr.length - 1 ? arr[i + 1] : 0)
      );
      let loadCalibratedWhole = loadCalibratedQuarter.map(
        (val, i, arr) =>
          val +
          (i < arr.length - 1 ? arr[i + 1] : 0) +
          (i < arr.length - 2 ? arr[i + 2] : 0) +
          (i < arr.length - 3 ? arr[i + 3] : 0)
      );
      let loadCalibratedHalf = loadCalibratedQuarter.map(
        (val, i, arr) => val + (i < arr.length - 1 ? arr[i + 1] : 0)
      );
      return {
        tag: item.tag,
        concerned: item.ratio > 0,
        // area: area.identifier,
        // models: area.models,
        ratio: item.ratio,
        flowOriginalQuarter,
        flowOriginalHalf,
        flowOriginalWhole,
        flowCalibratedQuarter,
        flowCalibratedHalf,
        flowCalibratedWhole,
        loadOriginalQuarter,
        loadOriginalHalf,
        loadOriginalWhole,
        loadCalibratedQuarter,
        loadCalibratedHalf,
        loadCalibratedWhole,
      };
    });
    let summary = {
      // moment: new Array(length).fill(""),
      flowOriginalQuarter: new Array(length).fill(0),
      flowOriginalHalf: new Array(length).fill(0),
      flowOriginalWhole: new Array(length).fill(0),
      flowCalibratedQuarter: new Array(length).fill(0),
      flowCalibratedHalf: new Array(length).fill(0),
      flowCalibratedWhole: new Array(length).fill(0),
      loadOriginalQuarter: new Array(length).fill(0),
      loadOriginalHalf: new Array(length).fill(0),
      loadOriginalWhole: new Array(length).fill(0),
      loadCalibratedQuarter: new Array(length).fill(0),
      loadCalibratedHalf: new Array(length).fill(0),
      loadCalibratedWhole: new Array(length).fill(0),
      // 0:idle, 1:easy, 3:fit, 0:bussy, -10:overload,
      evaluationOriginalQuarter: new Array(length).fill(0),
      evaluationOriginalWhole: new Array(length).fill(0),
      evaluationCalibratedQuarter: new Array(length).fill(0),
      evaluationCalibratedWhole: new Array(length).fill(0),
    };
    details.forEach((item) => {
      for (let i = 0; i < length; i++) {
        summary.flowOriginalQuarter[i] += item.flowOriginalQuarter[i];
        summary.flowOriginalHalf[i] += item.flowOriginalHalf[i];
        summary.flowOriginalWhole[i] += item.flowOriginalWhole[i];
        summary.flowCalibratedQuarter[i] += item.flowCalibratedQuarter[i];
        summary.flowCalibratedHalf[i] += item.flowCalibratedHalf[i];
        summary.flowCalibratedWhole[i] += item.flowCalibratedWhole[i];
        summary.loadOriginalQuarter[i] += item.loadOriginalQuarter[i];
        summary.loadOriginalHalf[i] += item.loadOriginalHalf[i];
        summary.loadOriginalWhole[i] += item.loadOriginalWhole[i];
        summary.loadCalibratedQuarter[i] += item.loadCalibratedQuarter[i];
        summary.loadCalibratedHalf[i] += item.loadCalibratedHalf[i];
        summary.loadCalibratedWhole[i] += item.loadCalibratedWhole[i];
      }
    });

    for (let i = 0; i < length; i++) {
      // 0:idle, 1:easy, 3:fit, 0:bussy, -10:overload,
      summary.evaluationOriginalQuarter[i] = evaluate(
        summary.loadOriginalQuarter[i],
        area.limits.baselineQuarter,
        area.limits.maximumQuarter
      );
      summary.evaluationOriginalWhole[i] = evaluate(
        summary.loadOriginalWhole[i],
        area.limits.baselineHour,
        area.limits.maximumHour
      );
      summary.evaluationCalibratedQuarter[i] = evaluate(
        summary.loadCalibratedQuarter[i],
        area.limits.baselineQuarter,
        area.limits.maximumQuarter
      );
      summary.evaluationCalibratedWhole[i] = evaluate(
        summary.loadCalibratedWhole[i],
        area.limits.baselineHour,
        area.limits.maximumHour
      );
      //  {
      //    "maximumHour": 2160,
      //    "baselineHour": 2160,
      //    "maximumQuarter": 720,
      //    "baselineQuarter": 720
      //  }
    }
    return {
      id: area.identifier,
      models: area.models,
      summary,
      // details,
      details: details.filter((item) => item.concerned),
    };
  });
  // console.log("areaCompute", result);
  return result;
};

const evaluate = (value, baseline, maximum) => {
  if (baseline == maximum) {
    return evaluateAncient(value, baseline);
  } else {
    return evaluateModern(value, baseline);
  }
};
// baseline == maximum
//   ? evaluateAncient(value, baseline)
//   : evaluateModern(value, baseline, maximum);

const evaluateAncient = (value, baseline) => {
  let result = null;
  // 0:idle, 1:easy, 3:fit, 0:bussy, -10:overload,
  if (value >= baseline) {
    result = -100;
    // result = "overload";
    // result = "O";
  } else if (value >= baseline * 0.85) {
    result = 0;
    // result = "bussy";
    // result = "B";
  } else if (value >= baseline * 0.6) {
    result = 15;
    // result = "fit";
    // result = "F";
  } else if (value >= baseline * 0.3) {
    result = 5;
    // result = "easy";
    // result = "E";
  } else {
    result = 1;
    // result = "idle";
    // result = "I";
  }
  return result;
};

const evaluateModern = (value, baseline, maximum) => {
  // 0:idle, 1:easy, 3:fit, 0:bussy, -10:overload,
  let gap = maximum - baseline;
  let bussyRange = [baseline + gap * 0.5, maximum];
  let fitRange = [baseline - gap * 0.5, baseline + gap * 0.5];
  let easyRange = [baseline - gap, baseline - gap * 0.5];
  let result = null;
  if (value > maximum) {
    result = -100;
    // result = "overload";
    // result = "O";
  } else if (value >= bussyRange[0] && value <= bussyRange[1]) {
    result = 0;
    // result = "bussy";
    // result = "B";
  } else if (value >= fitRange[0] && value <= fitRange[1]) {
    result = 3;
    // result = "fit";
    // result = "F";
  } else if (value >= easyRange[0] && value <= easyRange[1]) {
    result = 1;
    // result = "easy";
    // result = "E";
  } else if (value <= easyRange[0]) {
    result = 0;
    // result = "idle";
    // result = "I";
  } else {
    // result = 0;
    // result = "unknow";
    result = "U";
  }
  // console.log("evaluate", value, baseline, maximum, fitRange, result);
  return result;
};

export default areaCompute;
